import { ServiceBaseX } from './order';
import { FNCManager } from './../utils/fnc/fncManager';
import { Terminal } from './../models/terminal';
import { Injectable } from '@angular/core';
import { Http, Headers, Jsonp, URLSearchParams } from '@angular/http';
import { ServiceBase } from './base';

interface Store {
    id: string;
}

export class SysSvr extends ServiceBaseX {
    private nodeSvrList: NodeService[] = [];
    private async checkFNSOnce() {
        return FNCManager.Current.IsConnect;
    }
    public async checkFBSOnce() {
        const millisec = 10000;
        let fnsSvr = new NodeService("FNS");
        fnsSvr.status = "checking";
        fnsSvr.errorTip = "请在收银台-设置-本地数据中心中开启“开启消息通知服务”";
        fnsSvr.describe = "消息通知服务";
        fnsSvr.onChange = (sender) => {
            this.DependentServiceChangedEvent(sender);
        }
        fnsSvr.checkOnce = () => {
            fnsSvr.status = FNCManager.Current.IsConnect ? "passed" : "failed";
            return fnsSvr;
        }
        fnsSvr.checkOnce()
        return fnsSvr
    }
    public async checkLDCOnce(ip?) {
        //register的时候加入进去 todo
        let ldcSvr = new NodeService("LDC");
        ldcSvr.errorTip = "请在收银台-设置-本地数据中心中开启“设置本终端为本地数据中心”";
        ldcSvr.describe = "数据中心服务";
        ldcSvr.status = "checking";
        ldcSvr.onChange = (sender) => {
            this.DependentServiceChangedEvent(sender);
        }
        ldcSvr.checkOnce = async () => {
            try {
                await this.ldcHeartbeat(ip);
                ldcSvr.status = "passed";
                return ldcSvr;
            } catch (error) {
                ldcSvr.status = "failed";
                throw ldcSvr
            }
        }
        return ldcSvr.checkOnce();
    }
    public getLDCConfig(LDCIp, config?) {
        const isSSL = location.protocol.indexOf("https") > -1;
        const port = isSSL ? 8886 : 8887;
        const protocol = isSSL ? "https://" : "http://";
        return this.get(protocol + LDCIp + ":" + port + "/api/system/getStoreId", config)
    }
    public async setAdsAbout() {
        try {
            const adsAbout = (await this.axiosGet("http://localhost:8866/about")).data;
            this.adsAbout = adsAbout;
        } catch (error) {
            this.adsAbout = { "retCode": 0, "version": "2.0", "ads_id": "FC:AA:14:BF:5D:23", "name": "MPJADS", "url": "http://172.16.255.145:8866", "adapterIds": ["FC:AA:14:BF:5D:23"] }
            !localStorage.getItem("debug") && alert("这个外壳有问题啊");
        }

    }
    public checkFbsOnce(sustain?) {
        let fbsSvr = new NodeService("FBS");
        fbsSvr.errorTip = "在收银台中进入'设置 - 本地数据中心', 点击 '配置服务'，勾选 '门店业务服务' 并确定";
        fbsSvr.describe = "门店业务服务(FBS)";
        fbsSvr.status = "checking";
        fbsSvr.onChange = (sender) => {
            this.DependentServiceChangedEvent(sender);
        }
        fbsSvr.checkOnce = async () => {
            try {
                await this.fbsHeartbeat();
                fbsSvr.status = "passed";
                return fbsSvr;
            } catch (error) {
                fbsSvr.status = "failed";
                throw fbsSvr
            }
        }
        return fbsSvr.checkOnce()
    }
    public async checkFNS(sustain: Boolean = true) {
        const millisec = 10000;
        let fnsSvr = new NodeService("FNS");
        fnsSvr.status = "checking";
        fnsSvr.errorTip = "请在收银台-设置-本地数据中心中开启“开启消息通知服务”";
        fnsSvr.describe = "消息通知服务";
        fnsSvr.onChange = (sender) => {
            this.DependentServiceChangedEvent(sender);
        }
        fnsSvr.checkOnce = () => {
            fnsSvr.status = FNCManager.Current.IsConnect ? "passed" : "failed";
            return fnsSvr;
        }
        sustain ? fnsSvr.check() : fnsSvr.checkOnce()
        return fnsSvr

    }
    public async getStoreFromLDC(): Promise<Store> {
        //如果LDC连接成功，就从LDC获取store的信息
        const store = {
            id: "cfdtzn8vb0o4g4488gw8wko4k"
        }//mock
        return store;
    }
    public async checkLDC(sustain: Boolean = true) {
        //register的时候加入进去 todo
        let ldcSvr = new NodeService("LDC");
        ldcSvr.errorTip = "请在收银台-设置-本地数据中心中开启“设置本终端为本地数据中心”";
        ldcSvr.describe = "数据中心服务";
        ldcSvr.status = "checking";
        ldcSvr.onChange = (sender) => {
            this.DependentServiceChangedEvent(sender);
        }
        ldcSvr.checkOnce = () => {
            return new Promise(async (resove, reject) => {
                setTimeout(function () {
                    ldcSvr.status = "passed";
                    resove(ldcSvr)
                }, 2000);
            })
        }
        sustain ? ldcSvr.check() : ldcSvr.checkOnce()
        return ldcSvr
    }
    public async checkFBS(sustain: Boolean = true) {
        let fbsSvr = new NodeService("FBS");
        fbsSvr.errorTip = "在收银台中进入'设置 - 本地数据中心', 点击 '配置服务'，勾选 '门店业务服务' 并确定";
        fbsSvr.describe = "门店业务服务(FBS)";
        fbsSvr.status = "checking";
        fbsSvr.onChange = (sender) => {
            this.DependentServiceChangedEvent(sender);
        }
        fbsSvr.checkOnce = () => {
            return new Promise(async (resove, reject) => {
                try {
                    //先使用这个 应该有心跳包 todo
                    await this.getOfFBS("/api/system/isOnline");
                    fbsSvr.status = "passed"
                    resove(fbsSvr)
                } catch (error) {
                    fbsSvr.status = "failed"
                    resove(fbsSvr)
                }
            })
        }
        sustain ? fbsSvr.check() : fbsSvr.checkOnce()
        //持续检测的先放进去
        this.nodeSvrList.push(fbsSvr);//?? todo 
        return fbsSvr
    }
    constructor() {
        super();
        //TODO:以后可以从配置文件加载
    }

    /**
     * 校验当前ldc服务的开启状态
     */
    CheckNodeService() {
        this.nodeSvrList.forEach(x => {
            x.check();
        });
    }
    /**
     * 获取当前ldc服务列表
     * @returns LDCServiceNode
     */
    getNodeSvrList(): NodeService[] {
        return this.nodeSvrList;
    }
    /**
     * 绑定终端
     */
    async BindTerminal(name: string) {
        let url = "/api/stores/" + this.store.id + "/terminals/bind/device";

        //设备信息的获取,从外壳中读取
        let postJson: Terminal = {
            id: "",
            name: name,
            deviceId: "",
            bound: true,
            boundApp: "mclerk",
            hardware: "Nexus",
            deviceType: "handheld",
            platform: "browser",
            platformVersion: "4.2",
            userAgent: "userAgent",
            os: "",
            store: this.store
        }
        if ((<any>window).device) {
            let device = (<any>window).device;
            let deviceInfo = device.getDeviceInfo();
            postJson.deviceId = deviceInfo.deviceId;
            postJson.deviceType = deviceInfo.deviceType;
            postJson.hardware = deviceInfo.hardware;
            postJson.platform = deviceInfo.platform;
            postJson.platformVersion = deviceInfo.platformVersion;
        }
        //todo 应该是 postOfClound 
        let r = await this.post(url, postJson);
        return r;
    }
    /**
     * 检查绑定的终端是否达到上限
     */
    async CheckTerminalLimt(): Promise<boolean> {
        let url = "/api/stores/" + this.store.id + "/terminals/limit";
        return this.get(url);
    }

    /**
     * LDC服务状态变更事件
     */
    DependentServiceChangedEvent: (sender: NodeService, args?: any) => void;
}


export class NodeService {
    public name: string;
    private _status: string;
    get status() {
        return this._status;
    }
    set status(value) {
        if (this._status != value) {
            this._status = value;
            this.onChange && this.onChange(this);
        }
    }
    onChange: (sender) => void
    constructor(name: string) {
        this.name = name;
    }
    describe: string;
    errorTip: string;
    checkOnce: () => void;
    //持续检测 todo
    check(millisec?) {
        setTimeout(async () => {
            await this.checkOnce && this.checkOnce();
            this.check();
        }, millisec || 10000)
    }
}


